 /*******************************************************************************
  * Copyright (c) 2000, 2006 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.ui.dialogs;

 import java.util.ArrayList ;
 import java.util.Arrays ;
 import java.util.Iterator ;
 import java.util.List ;
 import java.util.StringTokenizer ;
 import java.util.Vector ;

 import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.dialogs.IDialogSettings;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.swt.widgets.Widget;
 import org.eclipse.ui.IFileEditorMapping;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;

 /**
  * Abstract superclass for a typical export wizard's main page.
  * <p>
  * Clients may subclass this page to inherit its common destination resource
  * selection facilities.
  * </p>
  * <p>
  * Subclasses must implement
  * <ul>
  * <li><code>createDestinationGroup</code></li>
  * </ul>
  * </p>
  * <p>
  * Subclasses may override
  * <ul>
  * <li><code>allowNewContainerName</code></li>
  * </ul>
  * </p>
  * <p>
  * Subclasses may extend
  * <ul>
  * <li><code>handleEvent</code></li>
  * <li><code>internalSaveWidgetValues</code></li>
  * <li><code>updateWidgetEnablements</code></li>
  * </ul>
  * </p>
  * @deprecated use WizardExportResourcePage
  */
 public abstract class WizardExportPage extends WizardDataTransferPage {
     private IStructuredSelection currentResourceSelection;

     private List selectedResources;

     private List selectedTypes;

     private boolean exportCurrentSelection = false;

     private boolean exportAllResourcesPreSet = false;

     // widgets
 private Combo typesToExportField;

     private Button typesToExportEditButton;

     private Button exportAllTypesRadio;

     private Button exportSpecifiedTypesRadio;

     private Button resourceDetailsButton;

     private Label resourceDetailsDescription;

     private Text resourceNameField;

     private Button resourceBrowseButton;

     // initial value stores
 private boolean initialExportAllTypesValue = true;

     private String initialExportFieldValue;

     private String initialTypesFieldValue;

     // constants
 private static final String CURRENT_SELECTION = "<current selection>";//$NON-NLS-1$

     private static final String TYPE_DELIMITER = ",";//$NON-NLS-1$

     // dialog store id constants
 private static final String STORE_SELECTED_TYPES_ID = "WizardFileSystemExportPage1.STORE_SELECTED_TYPES_ID.";//$NON-NLS-1$

     private static final String STORE_EXPORT_ALL_RESOURCES_ID = "WizardFileSystemExportPage1.STORE_EXPORT_ALL_RESOURCES_ID.";//$NON-NLS-1$

     /**
      * Creates an export wizard page. If the current resource selection
      * is not empty then it will be used as the initial collection of resources
      * selected for export.
      *
      * @param pageName the name of the page
      * @param selection the current resource selection
      */
     protected WizardExportPage(String pageName, IStructuredSelection selection) {
         super(pageName);
         this.currentResourceSelection = selection;
     }

     /**
      * The <code>WizardExportPage</code> implementation of this
      * <code>WizardDataTransferPage</code> method returns <code>false</code>.
      * Subclasses may override this method.
      */
     protected boolean allowNewContainerName() {
         return false;
     }

     /** (non-Javadoc)
      * Method declared on IDialogPage.
      */
     public void createControl(Composite parent) {
         Composite composite = new Composite(parent, SWT.NULL);
         composite.setLayout(new GridLayout());
         composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL
                 | GridData.HORIZONTAL_ALIGN_FILL));

         createBoldLabel(composite, IDEWorkbenchMessages.WizardExportPage_whatLabel);
         createSourceGroup(composite);

         createSpacer(composite);

         createBoldLabel(composite, IDEWorkbenchMessages.WizardExportPage_whereLabel);
         createDestinationGroup(composite);

         createSpacer(composite);

         createBoldLabel(composite, IDEWorkbenchMessages.WizardExportPage_options);
         createOptionsGroup(composite);

         restoreResourceSpecificationWidgetValues(); // ie.- local
 restoreWidgetValues(); // ie.- subclass hook
 if (currentResourceSelection != null) {
             setupBasedOnInitialSelections();
         }

         updateWidgetEnablements();
         setPageComplete(determinePageCompletion());

         setControl(composite);
     }

     /**
      * Creates the export destination specification visual components.
      * <p>
      * Subclasses must implement this method.
      * </p>
      *
      * @param parent the parent control
      */
     protected abstract void createDestinationGroup(Composite parent);

     /**
      * Creates the export source resource specification controls.
      *
      * @param parent the parent control
      */
     protected final void createSourceGroup(Composite parent) {
         // top level group
 Composite sourceGroup = new Composite(parent, SWT.NONE);
         GridLayout layout = new GridLayout();
         layout.numColumns = 3;
         sourceGroup.setLayout(layout);
         sourceGroup.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL
                 | GridData.HORIZONTAL_ALIGN_FILL));

         // resource label
 new Label(sourceGroup, SWT.NONE).setText(IDEWorkbenchMessages.WizardExportPage_folder);

         // resource name entry field
 resourceNameField = new Text(sourceGroup, SWT.SINGLE | SWT.BORDER);
         resourceNameField.addListener(SWT.KeyDown, this);
         GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
                 | GridData.GRAB_HORIZONTAL);
         data.widthHint = SIZING_TEXT_FIELD_WIDTH;
         resourceNameField.setLayoutData(data);

         // resource browse button
 resourceBrowseButton = new Button(sourceGroup, SWT.PUSH);
         resourceBrowseButton.setText(IDEWorkbenchMessages.WizardExportPage_browse);
         resourceBrowseButton.addListener(SWT.Selection, this);
         resourceBrowseButton.setLayoutData(new GridData(
                 GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));

         // export all types radio
 exportAllTypesRadio = new Button(sourceGroup, SWT.RADIO);
         exportAllTypesRadio.setText(IDEWorkbenchMessages.WizardExportPage_allTypes);
         exportAllTypesRadio.addListener(SWT.Selection, this);
         data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
                 | GridData.GRAB_HORIZONTAL);
         data.horizontalSpan = 3;
         exportAllTypesRadio.setLayoutData(data);

         // export specific types radio
 exportSpecifiedTypesRadio = new Button(sourceGroup, SWT.RADIO);
         exportSpecifiedTypesRadio.setText(IDEWorkbenchMessages.WizardExportPage_specificTypes);
         exportSpecifiedTypesRadio.addListener(SWT.Selection, this);

         // types combo
 typesToExportField = new Combo(sourceGroup, SWT.NONE);
         data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
                 | GridData.GRAB_HORIZONTAL);
         data.widthHint = SIZING_TEXT_FIELD_WIDTH;
         typesToExportField.setLayoutData(data);
         typesToExportField.addListener(SWT.Modify, this);

         // types edit button
 typesToExportEditButton = new Button(sourceGroup, SWT.PUSH);
         typesToExportEditButton.setText(IDEWorkbenchMessages.WizardExportPage_edit);
         typesToExportEditButton.setLayoutData(new GridData(
                 GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL
                         | GridData.VERTICAL_ALIGN_END));
         typesToExportEditButton.addListener(SWT.Selection, this);

         // details button
 resourceDetailsButton = new Button(sourceGroup, SWT.PUSH);
         resourceDetailsButton.setText(IDEWorkbenchMessages.WizardExportPage_details);
         resourceDetailsButton.addListener(SWT.Selection, this);

         // details label
 resourceDetailsDescription = new Label(sourceGroup, SWT.NONE);
         data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
                 | GridData.GRAB_HORIZONTAL);
         data.horizontalSpan = 2;
         resourceDetailsDescription.setLayoutData(data);

         // initial setup
 resetSelectedResources();
         exportAllTypesRadio.setSelection(initialExportAllTypesValue);
         exportSpecifiedTypesRadio.setSelection(!initialExportAllTypesValue);
         typesToExportField.setEnabled(!initialExportAllTypesValue);
         typesToExportEditButton.setEnabled(!initialExportAllTypesValue);

         if (initialExportFieldValue != null) {
             resourceNameField.setText(initialExportFieldValue);
         }
         if (initialTypesFieldValue != null) {
             typesToExportField.setText(initialTypesFieldValue);
         }
     }

     /**
      * Display an error dialog with the specified message.
      *
      * @param message the error message
      */
     protected void displayErrorDialog(String message) {
         MessageDialog.openError(getContainer().getShell(), IDEWorkbenchMessages.WizardExportPage_errorDialogTitle, message);
     }

     /**
      * Displays a description message that indicates a selection of resources
      * of the specified size.
      *
      * @param selectedResourceCount the resource selection size to display
      */
     protected void displayResourcesSelectedCount(int selectedResourceCount) {
         if (selectedResourceCount == 1) {
             resourceDetailsDescription.setText(IDEWorkbenchMessages.WizardExportPage_oneResourceSelected);
         } else {
             resourceDetailsDescription
                     .setText(NLS.bind(IDEWorkbenchMessages.WizardExportPage_resourceCountMessage, new Integer (selectedResourceCount)));
         }
     }

     /**
      * Obsolete method. This was implemented to handle the case where ensureLocal()
      * needed to be called but it doesn't use it any longer.
      *
      * @param resources the list of resources to ensure locality for
      * @return <code>true</code> for successful completion
      * @deprecated Only retained for backwards compatibility.
      */
     protected boolean ensureResourcesLocal(List resources) {
         return true;
     }

     /**
      * Returns a new subcollection containing only those resources which are not
      * local.
      *
      * @param originalList the original list of resources (element type:
      * <code>IResource</code>)
      * @return the new list of non-local resources (element type:
      * <code>IResource</code>)
      */
     protected List extractNonLocalResources(List originalList) {
         Vector result = new Vector (originalList.size());
         Iterator resourcesEnum = originalList.iterator();

         while (resourcesEnum.hasNext()) {
             IResource currentResource = (IResource) resourcesEnum.next();
             if (!currentResource.isLocal(IResource.DEPTH_ZERO)) {
                 result.addElement(currentResource);
             }
         }

         return result;
     }

     /**
      * Returns the current selection value of the "Export all types" radio,
      * or its set initial value if it does not exist yet.
      *
      * @return the "Export All Types" radio's current value or anticipated initial
      * value
      */
     public boolean getExportAllTypesValue() {
         if (exportAllTypesRadio == null) {
             return initialExportAllTypesValue;
         }

         return exportAllTypesRadio.getSelection();
     }

     /**
      * Returns the current contents of the resource name entry field,
      * or its set initial value if it does not exist yet (which could
      * be <code>null</code>).
      *
      * @return the resource name field's current value or anticipated initial value,
      * or <code>null</code>
      */
     public String getResourceFieldValue() {
         if (resourceNameField == null) {
             return initialExportFieldValue;
         }

         return resourceNameField.getText();
     }

     /**
      * Return the path for the resource field.
      * @return org.eclipse.core.runtime.IPath
      */
     protected IPath getResourcePath() {
         return getPathFromText(this.resourceNameField);
     }

     /**
      * Returns this page's collection of currently-specified resources to be
      * exported. This is the primary resource selection facility accessor for
      * subclasses.
      *
      * @return the collection of resources currently selected for export (element
      * type: <code>IResource</code>)
      */
     protected List getSelectedResources() {
         if (selectedResources == null) {
             IResource sourceResource = getSourceResource();

             if (sourceResource != null) {
                 selectAppropriateResources(sourceResource);
             }
         }

         return selectedResources;
     }

     /**
      * Returns the resource object specified in the resource name entry field,
      * or <code>null</code> if such a resource does not exist in the workbench.
      *
      * @return the resource specified in the resource name entry field, or
      * <code>null</code>
      */
     protected IResource getSourceResource() {
         IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace();
         //make the path absolute to allow for optional leading slash
 IPath testPath = getResourcePath();

         IStatus result = workspace.validatePath(testPath.toString(),
                 IResource.ROOT | IResource.PROJECT | IResource.FOLDER
                         | IResource.FILE);

         if (result.isOK() && workspace.getRoot().exists(testPath)) {
             return workspace.getRoot().findMember(testPath);
         }

         return null;
     }

     /**
      * Returns the current contents of the types entry field, or its set
      * initial value if it does not exist yet (which could be <code>null</code>).
      *
      * @return the types entry field's current value or anticipated initial value,
      * or <code>null</code>
      */
     public String getTypesFieldValue() {
         if (typesToExportField == null) {
             return initialTypesFieldValue;
         }

         return typesToExportField.getText();
     }

     /**
      * Returns the resource extensions currently specified to be exported.
      *
      * @return the resource extensions currently specified to be exported (element
      * type: <code>String</code>)
      */
     protected List getTypesToExport() {
         List result = new ArrayList ();
         StringTokenizer tokenizer = new StringTokenizer (typesToExportField
                 .getText(), TYPE_DELIMITER);

         while (tokenizer.hasMoreTokens()) {
             String currentExtension = tokenizer.nextToken().trim();
             if (!currentExtension.equals("")) { //$NON-NLS-1$
 result.add(currentExtension);
             }
         }

         return result;
     }

     /**
      * The <code>WizardExportPage</code> implementation of this
      * <code>Listener</code> method handles all events and enablements for controls
      * on this page. Subclasses may extend.
      */
     public void handleEvent(Event event) {
         Widget source = event.widget;

         if (source == exportAllTypesRadio || source == typesToExportField
                 || source == resourceNameField) {
             resetSelectedResources();
         } else if (source == exportSpecifiedTypesRadio) {
             resetSelectedResources();
             typesToExportField.setFocus();
         } else if (source == resourceDetailsButton) {
             handleResourceDetailsButtonPressed();
         } else if (source == resourceBrowseButton) {
             handleResourceBrowseButtonPressed();
         } else if (source == typesToExportEditButton) {
             handleTypesEditButtonPressed();
         }

         setPageComplete(determinePageCompletion());
         updateWidgetEnablements();
     }

     /**
      * Opens a container selection dialog and displays the user's subsequent
      * container selection in this page's resource name field.
      */
     protected void handleResourceBrowseButtonPressed() {
         IResource currentFolder = getSourceResource();
         if (currentFolder != null && currentFolder.getType() == IResource.FILE) {
             currentFolder = currentFolder.getParent();
         }

         IPath containerPath = queryForContainer((IContainer) currentFolder,
                 IDEWorkbenchMessages.WizardExportPage_selectResourcesToExport);
         if (containerPath != null) { // null means user cancelled
 String relativePath = containerPath.makeRelative().toString();
             if (!relativePath.toString().equals(resourceNameField.getText())) {
                 resetSelectedResources();
                 resourceNameField.setText(relativePath);
             }
         }
     }

     /**
      * Opens a resource selection dialog and records the user's subsequent
      * resource selections.
      */
     protected void handleResourceDetailsButtonPressed() {
         IAdaptable source = getSourceResource();

         if (source == null) {
             source = ResourcesPlugin.getWorkspace().getRoot();
         }

         selectAppropriateResources(source);

         if (source instanceof IFile) {
             source = ((IFile) source).getParent();
             setResourceToDisplay((IResource) source);
         }

         Object [] newlySelectedResources = queryIndividualResourcesToExport(source);

         if (newlySelectedResources != null) {
             selectedResources = Arrays.asList(newlySelectedResources);
             displayResourcesSelectedCount(selectedResources.size());
         }
     }

     /**
      * Queries the user for the types of resources to be exported and
      * displays these types in this page's "Types to export" field.
      */
     protected void handleTypesEditButtonPressed() {
         Object [] newSelectedTypes = queryResourceTypesToExport();

         if (newSelectedTypes != null) { // ie.- did not press Cancel
 List result = new ArrayList (newSelectedTypes.length);
             for (int i = 0; i < newSelectedTypes.length; i++) {
                 result.add(((IFileEditorMapping) newSelectedTypes[i])
                         .getExtension());
             }
             setTypesToExport(result);
         }
     }

     /**
      * Returns whether the extension of the given resource name is an extension that
      * has been specified for export by the user.
      *
      * @param resourceName the resource name
      * @return <code>true</code> if the resource name is suitable for export based
      * upon its extension
      */
     protected boolean hasExportableExtension(String resourceName) {
         if (selectedTypes == null) {
             return true;
         }

         int separatorIndex = resourceName.lastIndexOf(".");//$NON-NLS-1$
 if (separatorIndex == -1) {
             return false;
         }

         String extension = resourceName.substring(separatorIndex + 1);

         Iterator it = selectedTypes.iterator();
         while (it.hasNext()) {
             if (extension.equalsIgnoreCase((String ) it.next())) {
                 return true;
             }
         }

         return false;
     }

     /**
      * Persists additional setting that are to be restored in the next instance of
      * this page.
      * <p>
      * The <code>WizardImportPage</code> implementation of this method does
      * nothing. Subclasses may extend to persist additional settings.
      * </p>
      */
     protected void internalSaveWidgetValues() {
     }

     /**
      * Queries the user for the individual resources that are to be exported
      * and returns these resources as a collection.
      *
      * @param rootResource the resource to use as the root of the selection query
      * @return the resources selected for export (element type:
      * <code>IResource</code>), or <code>null</code> if the user canceled the
      * selection
      */
     protected Object [] queryIndividualResourcesToExport(IAdaptable rootResource) {
         ResourceSelectionDialog dialog = new ResourceSelectionDialog(
                 getContainer().getShell(), rootResource, IDEWorkbenchMessages.WizardExportPage_selectResourcesTitle);
         dialog.setInitialSelections(selectedResources
                 .toArray(new Object [selectedResources.size()]));
         dialog.open();
         return dialog.getResult();
     }

     /**
      * Queries the user for the resource types that are to be exported and returns
      * these types as a collection.
      *
      * @return the resource types selected for export (element type:
      * <code>String</code>), or <code>null</code> if the user canceled the
      * selection
      */
     protected Object [] queryResourceTypesToExport() {
         IFileEditorMapping editorMappings[] = PlatformUI.getWorkbench()
                 .getEditorRegistry().getFileEditorMappings();

         int mappingsSize = editorMappings.length;
         List selectedTypes = getTypesToExport();
         List initialSelections = new ArrayList (selectedTypes.size());

         for (int i = 0; i < mappingsSize; i++) {
             IFileEditorMapping currentMapping = editorMappings[i];
             if (selectedTypes.contains(currentMapping.getExtension())) {
                 initialSelections.add(currentMapping);
             }
         }

         ListSelectionDialog dialog = new ListSelectionDialog(getContainer()
                 .getShell(), editorMappings,
                 FileEditorMappingContentProvider.INSTANCE,
                 FileEditorMappingLabelProvider.INSTANCE, IDEWorkbenchMessages.WizardExportPage_selectionDialogMessage);

         dialog.setTitle(IDEWorkbenchMessages.WizardExportPage_resourceTypeDialog);
         dialog.open();

         return dialog.getResult();
     }

     /**
      * Resets this page's selected resources collection and updates its controls
      * accordingly.
      */
     protected void resetSelectedResources() {
         resourceDetailsDescription.setText(IDEWorkbenchMessages.WizardExportPage_detailsMessage);
         selectedResources = null;

         if (exportCurrentSelection) {
             exportCurrentSelection = false;

             if (resourceNameField.getText().length() > CURRENT_SELECTION
                     .length()) {
                 resourceNameField.setText(resourceNameField.getText()
                         .substring(CURRENT_SELECTION.length()));
             } else {
                 resourceNameField.setText("");//$NON-NLS-1$
 }
         }
     }

     /**
      * Restores resource specification control settings that were persisted
      * in the previous instance of this page. Subclasses wishing to restore
      * persisted values for their controls may extend.
      */
     protected void restoreResourceSpecificationWidgetValues() {
         IDialogSettings settings = getDialogSettings();
         if (settings != null) {
             String pageName = getName();
             boolean exportAllResources = settings
                     .getBoolean(STORE_EXPORT_ALL_RESOURCES_ID + pageName);

             // restore all/typed radio values iff not already explicitly set
 if (!exportAllResourcesPreSet) {
                 exportAllTypesRadio.setSelection(exportAllResources);
                 exportSpecifiedTypesRadio.setSelection(!exportAllResources);
             }

             // restore selected types iff not explicitly already set
 if (initialTypesFieldValue == null) {
                 String [] selectedTypes = settings
                         .getArray(STORE_SELECTED_TYPES_ID + pageName);
                 if (selectedTypes != null) {
                     if (selectedTypes.length > 0) {
                         typesToExportField.setText(selectedTypes[0]);
                     }
                     for (int i = 0; i < selectedTypes.length; i++) {
                         typesToExportField.add(selectedTypes[i]);
                     }
                 }
             }
         }
     }

     /**
      * Persists resource specification control setting that are to be restored
      * in the next instance of this page. Subclasses wishing to persist additional
      * setting for their controls should extend hook method
      * <code>internalSaveWidgetValues</code>.
      */
     protected void saveWidgetValues() {
         IDialogSettings settings = getDialogSettings();
         if (settings != null) {
             String pageName = getName();

             // update specific types to export history
 String [] selectedTypesNames = settings
                     .getArray(STORE_SELECTED_TYPES_ID + pageName);
             if (selectedTypesNames == null) {
                 selectedTypesNames = new String [0];
             }

             if (exportSpecifiedTypesRadio.getSelection()) {
                 selectedTypesNames = addToHistory(selectedTypesNames,
                         typesToExportField.getText());
             }

             settings
                     .put(STORE_SELECTED_TYPES_ID + pageName, selectedTypesNames);

             // radio buttons
 settings.put(STORE_EXPORT_ALL_RESOURCES_ID + pageName,
                     exportAllTypesRadio.getSelection());
         }

         // allow subclasses to save values
 internalSaveWidgetValues();

     }

     /**
      * Records a container's recursive file descendents which have an extension
      * that has been specified for export by the user.
      *
      * @param resource the parent container
      */
     protected void selectAppropriateFolderContents(IContainer resource) {
         try {
             IResource[] members = resource.members();

             for (int i = 0; i < members.length; i++) {
                 if (members[i].getType() == IResource.FILE) {
                     IFile currentFile = (IFile) members[i];
                     if (hasExportableExtension(currentFile.getFullPath()
                             .toString())) {
                         selectedResources.add(currentFile);
                     }
                 }
                 if (members[i].getType() == IResource.FOLDER) {
                     selectAppropriateFolderContents((IContainer) members[i]);
                 }
             }
         } catch (CoreException e) {
             //don't show children if there are errors -- should at least log this
 }
     }

     /**
      * Records a resource's recursive descendents which are appropriate
      * for export based upon this page's current controls contents.
      *
      * @param resource the parent resource
      */
     protected void selectAppropriateResources(Object resource) {
         if (selectedResources == null) {

             if (exportSpecifiedTypesRadio.getSelection()) {
                 selectedTypes = getTypesToExport();
             } else {
                 selectedTypes = null; // sentinel for select all extensions
 }

             selectedResources = new ArrayList ();
             if (resource instanceof IWorkspaceRoot) {
                 IProject[] projects = ((IWorkspaceRoot) resource).getProjects();
                 for (int i = 0; i < projects.length; i++) {
                     selectAppropriateFolderContents(projects[i]);
                 }
             } else if (resource instanceof IFile) {
                 IFile file = (IFile) resource;
                 if (hasExportableExtension(file.getFullPath().toString())) {
                     selectedResources.add(file);
                 }
             } else {
                 selectAppropriateFolderContents((IContainer) resource);
             }
         }
     }

     /**
      * Sets the selection value of this page's "Export all types" radio, or stores
      * it for future use if this visual component does not exist yet.
      *
      * @param value new selection value
      */
     public void setExportAllTypesValue(boolean value) {
         if (exportAllTypesRadio == null) {
             initialExportAllTypesValue = value;
             exportAllResourcesPreSet = true;
         } else {
             exportAllTypesRadio.setSelection(value);
             exportSpecifiedTypesRadio.setSelection(!value);
         }
     }

     /**
      * Sets the value of this page's source resource field, or stores
      * it for future use if this visual component does not exist yet.
      *
      * @param value new value
      */
     public void setResourceFieldValue(String value) {
         if (resourceNameField == null) {
             initialExportFieldValue = value;
         } else {
             resourceNameField.setText(value);
         }
     }

     /**
      * Set the resource whos name we will display.
      * @param resource
      */
     protected void setResourceToDisplay(IResource resource) {
         setResourceFieldValue(resource.getFullPath().makeRelative().toString());
     }

     /**
      * Sets the value of this page's "Types to export" field, or stores
      * it for future use if this visual component does not exist yet.
      *
      * @param value new value
      */
     public void setTypesFieldValue(String value) {
         if (typesToExportField == null) {
             initialTypesFieldValue = value;
         } else {
             typesToExportField.setText(value);
         }
     }

     /**
      * Sets the value of this page's "Types to export" field based upon the
      * collection of extensions.
      *
      * @param typeStrings the collection of extensions to populate the "Types to
      * export" field with (element type: <code>String</code>)
      */
     protected void setTypesToExport(List typeStrings) {
         StringBuffer result = new StringBuffer ();
         Iterator typesEnum = typeStrings.iterator();

         while (typesEnum.hasNext()) {
             result.append(typesEnum.next());
             result.append(TYPE_DELIMITER);
             result.append(" ");//$NON-NLS-1$
 }

         typesToExportField.setText(result.toString());
     }

     /**
      * Populates the resource name field based upon the currently selected resources.
      */
     protected void setupBasedOnInitialSelections() {
         if (initialExportFieldValue != null) {
             // a source resource has been programatically specified, which overrides
 // the current workbench resource selection
 IResource specifiedSourceResource = getSourceResource();
             if (specifiedSourceResource == null) {
                 currentResourceSelection = new StructuredSelection();
             } else {
                 currentResourceSelection = new StructuredSelection(
                         specifiedSourceResource);
             }
         }

         if (currentResourceSelection.isEmpty()) {
             return; // no setup needed
 }

         List selections = new ArrayList ();
         Iterator it = currentResourceSelection.iterator();
         while (it.hasNext()) {
             IResource currentResource = (IResource) it.next();
             // do not add inaccessible elements
 if (currentResource.isAccessible()) {
                 selections.add(currentResource);
             }
         }

         if (selections.isEmpty()) {
             return; // setup not needed anymore
 }

         int selectedResourceCount = selections.size();
         if (selectedResourceCount == 1) {
             IResource resource = (IResource) selections.get(0);
             setResourceToDisplay(resource);
         } else {
             selectedResources = selections;
             exportAllTypesRadio.setSelection(true);
             exportSpecifiedTypesRadio.setSelection(false);
             resourceNameField.setText(CURRENT_SELECTION);
             exportCurrentSelection = true;
             displayResourcesSelectedCount(selectedResourceCount);
         }
     }

     /**
      * Updates the enablements of this page's controls. Subclasses may extend.
      */
     protected void updateWidgetEnablements() {
         if (exportCurrentSelection) {
             resourceDetailsButton.setEnabled(true);
         } else {
             IResource resource = getSourceResource();
             resourceDetailsButton.setEnabled(resource != null
                     && resource.isAccessible());
         }

         exportSpecifiedTypesRadio.setEnabled(!exportCurrentSelection);
         typesToExportField.setEnabled(exportSpecifiedTypesRadio.getSelection());
         typesToExportEditButton.setEnabled(exportSpecifiedTypesRadio
                 .getSelection());
     }

     /* (non-Javadoc)
      * Method declared on WizardDataTransferPage.
      */
     protected final boolean validateSourceGroup() {
         if (exportCurrentSelection) {
             return true;
         }

         String sourceString = resourceNameField.getText();
         if (sourceString.equals("")) {//$NON-NLS-1$
 setErrorMessage(null);
             return false;
         }

         IResource resource = getSourceResource();

         if (resource == null) {
             setErrorMessage(IDEWorkbenchMessages.WizardExportPage_mustExistMessage);
             return false;
         }

         if (!resource.isAccessible()) {
             setErrorMessage(IDEWorkbenchMessages.WizardExportPage_mustBeAccessibleMessage);
             return false;
         }

         return true;
     }
 }

